package com.zhengx.fragmentutil;


import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;

import java.util.List;

/**
 * name：com.zhengx.fragmentutil
 * class: fragment工具类
 *  findController方法必须在设置了view以后调用，比如Activity的setContentView后，fragment的onCreateView或者onViewCreated中
 * author: zhengx
 * create_time: 2019/5/6
 */
public class FragmentUtil {

    /**
     * @return 返回Activity下第一个FragContainer对应的FragController;
     */
    public synchronized static FragController findController(@NonNull FragmentActivity fragmentActivity) {
        List<Fragment> fragments = fragmentActivity.getSupportFragmentManager().getFragments();
        for (Fragment fragment : fragments) {
            if (fragment instanceof FragContainer) {
                return ((FragContainer) fragment).getController();
            }

        }
        throw new NullPointerException("没有找到指定id的FragContainer");
    }

    /**
     * @return 返回Activity下指定id的FragContainer对应的FragController;
     */
    public synchronized static FragController findController(@NonNull FragmentActivity fragmentActivity, int containerId) {
        List<Fragment> fragments = fragmentActivity.getSupportFragmentManager().getFragments();
        for (Fragment fragment : fragments) {
            if (fragment instanceof FragContainer) {
                if (fragment.getId() == containerId) {
                    return ((FragContainer) fragment).getController();
                }
            }

        }
        throw new NullPointerException("没有找到指定id的FragContainer");
    }

    /**
     * 向上查找给定Fragment的FragController，先查找fragment的子元素，然后查找parent，直到parent为null
     */
    public synchronized static FragController findController(@NonNull Fragment fragment) {

        if (fragment instanceof FragContainer) {
            return ((FragContainer) fragment).getController();
        }
        List<Fragment> fragments = fragment.getChildFragmentManager().getFragments();
        for (Fragment temp : fragments) {
            if (temp instanceof FragContainer) {
                return ((FragContainer) temp).getController();
            }
        }
        Fragment parent = fragment.getParentFragment();
        while (parent != null) {
            if (parent instanceof  FragContainer) {
                return ((FragContainer) parent).getController();
            }
            parent = parent.getParentFragment();
        }
        throw new NullPointerException("没有找到给定Fragment的容器，请先在给定fragment的布局中指定FragContainer");
    }

    /**
     * 向上查找给定Fragment的FragController，直到parent为null
     */
    public synchronized static FragController findController(@NonNull Fragment fragment, int containerId) {

        if (fragment instanceof FragContainer) {
            return ((FragContainer) fragment).getController();
        }
        List<Fragment> fragments = fragment.getChildFragmentManager().getFragments();
        for (Fragment temp : fragments) {
            if (temp instanceof FragContainer) {
                if (temp.getId() == containerId) {
                    return ((FragContainer) temp).getController();
                }
            }
        }
        Fragment parent = fragment.getParentFragment();
        while (parent != null) {
            if (parent instanceof  FragContainer) {
                return ((FragContainer) parent).getController();
            }
            parent = parent.getParentFragment();
        }
        throw new NullPointerException("没有找到给定Fragment的容器，请先在给定fragment的布局中指定FragContainer");
    }

    /**
     * 处理fragment生命周期相关功能；目前主要用于可见状态变化的处理
     */
    public static FragmentHandlerDelegate setupDelegate(@NonNull Fragment fragment) {

        return new FragmentHandlerDelegate(fragment);
    }

    /**
     * 在需要处理fragment返回事件的Activity的onBackPressed中必须调用该方法
     * 根据返回值判断是否已有fragment处理了返回键
     * eg:
     * if (!FragmentUtil.handleFragmentsBackPressed(this)) {
     *     super.onBackPressed();
     * }
     * @return true表示已经处理了返回键，否则没有处理
     */
    public static boolean handleFragmentsBackPressed(@NonNull FragmentActivity fragmentActivity) {
        return BackPressedHandler.handleBackPress(fragmentActivity);
    }

    /**
     * 在fragment的{@link IFragmentBackHandler#onBackPressed()}中调用（用于向下传递返回键事件）；
     * 如果明确不用再向下传递事件，可以直接返回false。
     * @param fragment
     * @return true表示拦截了返回键事件，不再向下传递
     */
    public static boolean handleFragmentsBackPressed(@NonNull Fragment fragment) {
        return BackPressedHandler.handleBackPress(fragment);
    }
}
